package itypes

import (
	"server/game/model"

	"github.com/hwcer/updater"
	"github.com/hwcer/updater/operator"
	"github.com/hwcer/yyds/errors"
)

var Loading bool

type Stacked func(int32) bool
type Unique func(u *updater.Updater, iid int32) string
type Creator func(u *updater.Updater, iid int32, val int64) (r any, err error)
type Listener func(u *updater.Updater, op *operator.Operator)

func ITypeUNStacked(iid int32) bool {
	return false
}

func NewIType(id int32, l ...Listener) *IType {
	it := &IType{id: id}
	if len(l) > 0 {
		it.listener = l[0]
	}
	return it
}

type IType struct {
	id       int32
	unique   Unique
	stacked  Stacked
	creator  Creator
	listener Listener
}

func (this *IType) ID() int32 {
	return this.id
}

func (this *IType) New(u *updater.Updater, op *operator.Operator) (any, error) {
	return this.Create(u, op.IID, op.Value)
}

func (this *IType) Create(u *updater.Updater, iid int32, val int64) (any, error) {
	if this.creator != nil {
		return this.creator(u, iid, val)
	} else {
		return nil, errors.Errorf(0, "create fail IType:%d, iid:%d", this.ID(), iid)
	}
}

func (this *IType) Stacked(iid int32) bool {
	if this.stacked == nil {
		return true
	}
	return this.stacked(iid)
}

func (this *IType) ObjectId(u *updater.Updater, iid int32) string {
	if this.unique != nil {
		return this.unique(u, iid)
	}
	if this.Stacked(iid) {
		return model.Unique(u, iid)
	} else {
		return model.ObjectId.New(uint64(iid))
	}
}

func (this *IType) Listener(u *updater.Updater, op *operator.Operator) {
	if this.listener != nil {
		this.listener(u, op)
	}
}

func (this *IType) SetUnique(unique Unique) {
	this.unique = unique
}
func (this *IType) SetStacked(stacked Stacked) {
	this.stacked = stacked
}
func (this *IType) SetCreator(creator Creator) {
	this.creator = creator
}

func (this *IType) SetListener(l Listener) {
	this.listener = l
}
